home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / STYLESHT.PAK / STYLESHT.CPP next >
C/C++ Source or Header  |  1997-05-06  |  9KB  |  274 lines

  1. // Borland C++ - (C) Copyright 1991, 1992 by Borland International
  2. //
  3. //  IDE Style Sheet example
  4.  
  5. #define  STRICT
  6. #include <windows.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. LRESULT CALLBACK _export WndProc( HWND hWnd, UINT iMessage,
  11.                                  WPARAM wParam, LPARAM lParam );
  12.  
  13. class Main
  14. {
  15. public:
  16.   static HINSTANCE hInstance;
  17.   static HINSTANCE hPrevInstance;
  18.   static int nCmdShow;
  19.   static int MessageLoop( void );
  20. };
  21.  
  22. class Window
  23. {
  24. protected:
  25.     HWND hWnd;
  26. public:
  27.     // Provide (read) access to the window's handle in case it is needed
  28.     // elsewhere.
  29.     HWND GetHandle( void ) { return hWnd; }
  30.  
  31.     BOOL Show( int nCmdShow ) { return ShowWindow( hWnd, nCmdShow ); }
  32.     void Update( void ) { UpdateWindow( hWnd ); }
  33.     // Pure virtual function makes Window an abstract class.
  34.     virtual LRESULT WndProc( UINT iMessage, WPARAM wParam, LPARAM lParam ) = 0;
  35. };
  36.  
  37. class MainWindow : public Window
  38. {
  39. private:
  40.     static char szClassName[];
  41.     
  42. public:
  43.     // Register the class only AFTER WinMain assigns appropriate
  44.     // values to static members of Main and only if no previous
  45.     // instances of the program exist (a previous instance would
  46.     // have already performed the registration).
  47.     static void Register( void )
  48.     {
  49.         WNDCLASS wndclass;   // Structure used to register Windows class.
  50.  
  51.         wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  52.         wndclass.lpfnWndProc   = ::WndProc;
  53.         wndclass.cbClsExtra    = 0;
  54.         // Reserve extra bytes for each instance of the window;
  55.         // we will use these bytes to store a pointer to the C++
  56.         // (MainWindow) object corresponding to the window.
  57.         // the size of a 'this' pointer depends on the memory model.
  58.         wndclass.cbWndExtra    = sizeof( MainWindow * );
  59.         wndclass.hInstance     = Main::hInstance;
  60.         wndclass.hIcon         = LoadIcon( Main::hInstance, "stylesht" );
  61.         wndclass.hCursor       = LoadCursor( NULL, IDC_ARROW );
  62.         wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
  63.         wndclass.lpszMenuName  = NULL;
  64.         wndclass.lpszClassName = szClassName;
  65.  
  66.         if ( ! RegisterClass( &wndclass ) )
  67.             exit( FALSE );
  68.     }
  69.  
  70.     // Do not create unless previously registered.
  71.     MainWindow( void )
  72.     {
  73.         // Pass 'this' pointer in lpParam of CreateWindow().
  74.         hWnd = CreateWindow( szClassName,
  75.             szClassName,
  76.             WS_OVERLAPPEDWINDOW,
  77.             CW_USEDEFAULT,
  78.             0,
  79.             CW_USEDEFAULT,
  80.             0,
  81.             NULL,
  82.             NULL,
  83.             Main::hInstance,
  84.             (LPSTR) this );
  85.         if ( ! hWnd )
  86.             exit( FALSE );
  87.  
  88.         Show( Main::nCmdShow );
  89.         Update();
  90.     }
  91.     LRESULT WndProc( UINT iMessage, WPARAM wParam, LPARAM lParam );
  92.  
  93.     // Print a message in the client rectangle.
  94.     void Paint( void );
  95.     
  96. };
  97.  
  98. HINSTANCE Main::hInstance = 0;
  99. HINSTANCE Main::hPrevInstance = 0;
  100. int       Main::nCmdShow = 0;
  101.  
  102. int Main::MessageLoop( void )
  103. {
  104.     MSG msg;
  105.  
  106.     while( GetMessage( &msg, NULL, 0, 0 ) )
  107.     {
  108.         TranslateMessage( &msg );
  109.         DispatchMessage( &msg );
  110.     }
  111.     return msg.wParam;
  112. }
  113.  
  114. char MainWindow::szClassName[] = "Hello, Style Sheets!";
  115.  
  116. static char szMessage[] =
  117. {
  118.    "The graph above represents the way that"
  119.    " project options, StyleSheets and local"
  120.    " options on a node all interact to form"
  121.    " the options that will be passed to tools"
  122.    " at various stages of building the project."
  123.    " Note that the Options|Project menu item"
  124.    " behaves slightly different when your project"
  125.    " has a single top-level target."
  126.    " Always refer to the 'View options hierarchy'"
  127.    " menu option on any node's SpeedMenu. The"
  128.    " order of precedence always starts at the"
  129.    " node you are compiling or linking, working"
  130.    " your way up to the tool defaults."
  131. };
  132.    
  133. void MainWindow::Paint( void )
  134. {
  135.     PAINTSTRUCT ps;
  136.  
  137.     HDC hDC = BeginPaint( hWnd, &ps );
  138.  
  139.     HBITMAP bitmap = LoadBitmap( Main::hInstance, "StyleSht" );
  140.     HDC memDC = CreateCompatibleDC( hDC );
  141.     HBITMAP oldBitmap = (HBITMAP)SelectObject( memDC, bitmap );
  142.     BitBlt( hDC, 0, 0, 400, 200, memDC, 0, 0, SRCCOPY );
  143.     SelectObject( memDC, oldBitmap );
  144.     DeleteDC( memDC );
  145.     FreeResource( bitmap );
  146.  
  147.     HFONT   oldFont   = (HFONT)( SelectObject( hDC, 
  148.                                    GetStockObject( ANSI_VAR_FONT ) ) );
  149.     RECT   rc = { 0, 205, 400, 405 };
  150.     DrawText( hDC, szMessage, sizeof(szMessage) - 1, &rc, 
  151.                            DT_CENTER | DT_VCENTER | DT_WORDBREAK );
  152.     SelectObject( hDC, oldFont );                           
  153.     
  154.     EndPaint( hWnd, &ps );
  155. }
  156.  
  157. LRESULT MainWindow::WndProc( UINT iMessage, WPARAM wParam, LPARAM lParam )
  158. {
  159.     switch (iMessage)
  160.     {
  161.         case WM_CREATE:
  162.             break;
  163.         case WM_PAINT:
  164.             Paint();
  165.             break;
  166.         case WM_DESTROY:
  167.             PostQuitMessage( 0 );
  168.             break;
  169.         default:
  170.             return DefWindowProc( hWnd, iMessage, wParam, lParam );
  171.     }
  172.     return 0;
  173. }
  174.  
  175. // If data pointers are near pointers
  176. #if defined(__SMALL__) || defined(__MEDIUM__)
  177. inline Window *GetPointer( HWND hWnd )
  178. {
  179.     return (Window *) GetWindowWord( hWnd, 0 );
  180. }
  181. inline void SetPointer( HWND hWnd, Window *pWindow )
  182. {
  183.     SetWindowWord( hWnd, 0, (WORD) pWindow );
  184. }
  185.  
  186. // else pointers are far
  187. #elif defined(__LARGE__) || defined(__COMPACT__) || defined(__FLAT__)
  188. inline Window *GetPointer( HWND hWnd )
  189. {
  190.     return (Window *) GetWindowLong( hWnd, 0 );
  191. }
  192. inline void SetPointer( HWND hWnd, Window *pWindow )
  193. {
  194.     SetWindowLong( hWnd, 0, (LONG) pWindow );
  195. }
  196.  
  197. #else
  198.     #error Choose another memory model!
  199. #endif
  200.  
  201. LRESULT  CALLBACK _export WndProc( HWND hWnd, UINT iMessage, WPARAM wParam,
  202.                                  LPARAM lParam )
  203. {
  204.     // Pointer to the (C++ object that is the) window.
  205.     Window *pWindow = GetPointer( hWnd );
  206.  
  207.     // The pointer pWindow will have an invalid value if the WM_CREATE
  208.     // message has not yet been processed (we respond to the WM_CREATE
  209.     // message by setting the extra bytes to be a pointer to the
  210.     // (C++) object corresponding to the Window identified
  211.     // by hWnd).  The messages that
  212.     // precede WM_CREATE must be processed without using pWindow so we
  213.     // pass them to DefWindowProc.
  214.     // How do we know in general if the pointer pWindow is invalid?
  215.     // Simple: Windows allocates the window extra bytes using LocalAlloc
  216.     // which zero initializes memory; thus, pWindow will have a value of
  217.     // zero before we set the window extra bytes to the 'this' pointer.
  218.     // Caveat emptor: the fact that LocalAlloc will zero initialize the
  219.     // window extra bytes is not documented; therefore, it could change
  220.     // in the future.
  221.  
  222.     if ( pWindow == 0 )
  223.     {
  224.         if ( iMessage == WM_CREATE )
  225.         {
  226.             LPCREATESTRUCT lpcs;
  227.  
  228.             lpcs = (LPCREATESTRUCT) lParam;
  229.             pWindow = (Window *) lpcs->lpCreateParams;
  230.  
  231.             // Store a pointer to this object in the window's extra bytes;
  232.             // this will enable us to access this object (and its member
  233.             // functions) in WndProc where we are
  234.             // given only a handle to identify the window.
  235.             SetPointer( hWnd, pWindow );
  236.             // Now let the object perform whatever
  237.             // initialization it needs for WM_CREATE in its own
  238.             // WndProc.
  239.       return pWindow->WndProc( iMessage, wParam, lParam );
  240.         }
  241.         else
  242.             return DefWindowProc( hWnd, iMessage, wParam, lParam );
  243.     }
  244.     else
  245.         return pWindow->WndProc( iMessage, wParam, lParam );
  246. }
  247.  
  248. // Turn off warning: Parameter 'lpszCmdLine' is never used in function WinMain(unsigned int,unsigned int,char far*,int)
  249. #pragma argsused
  250.  
  251. // Turn off warning: 'MainWnd' is assigned a value that is never used in function WinMain(unsigned int,unsigned int,char far*,int)
  252. #pragma option -w-aus
  253.  
  254. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine,
  255.                     int nCmdShow )
  256. {
  257.     Main::hInstance = hInstance;
  258.     Main::hPrevInstance = hPrevInstance;
  259.     Main::nCmdShow = nCmdShow;
  260.  
  261.     // A Windows class should be registered with Windows before any windows
  262.     // of that type are created.
  263.     // Register here all Windows classes that will be used in the program.
  264.     // Windows classes should not be registered if an instance of
  265.     // the program is already running.
  266.     if ( ! Main::hPrevInstance ) {
  267.         MainWindow::Register();
  268.     }
  269.  
  270.     MainWindow MainWnd;
  271.  
  272.     return Main::MessageLoop();
  273. }
  274.